package cn.boat.router.consumer;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.util.Collections;
import java.util.List;

public class MyLock {
     // private String IP = "39.106.77.77:2181";
     private ZooKeeper zooKeeper = null;
     private static final String LOCK_ROOT_PARH = "/Locks";
     private static final String LOCK_NODE_NAME = "Lock_";
     private String lockPath;

     // 打开zookeeper连接
    public MyLock(ZooKeeper zooKeeperConnection){

        zooKeeper = zooKeeperConnection;

    }
     // 获取锁
    public void acquireLock()throws Exception {
        // 创建锁节点
        createLock();
        //尝试获取锁
        attempLock();
    }
    // 创建锁节点
    public void createLock() throws Exception {
        Stat stat = zooKeeper.exists(LOCK_ROOT_PARH,false);
        if (stat == null){
            zooKeeper.create(LOCK_ROOT_PARH,"Hello".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        //创建临时有序节点
        lockPath = zooKeeper.create(LOCK_ROOT_PARH+"/"+LOCK_NODE_NAME,new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println("节点创建成功"+lockPath);
    }
    Watcher watcher = new Watcher() {
        @Override
        public void process(WatchedEvent watchedEvent) {
            // 监视器对象 监视前一个临时节点的状态
            if (watchedEvent.getType() == Event.EventType.NodeDeleted){
                synchronized (this){
                    notifyAll();
                }
            }
        }
    };
    //获取锁节点
    public void attempLock()throws Exception {
        // 获取Locks下的所有子节点名称
        List<String> childrenList = zooKeeper.getChildren(LOCK_ROOT_PARH, false);
        Collections.sort(childrenList);
        // 完整路径名称为这种形式 /Locks/Lock_0000000000
        int index = childrenList.indexOf(lockPath.substring(LOCK_ROOT_PARH.length()+1));
        if (index ==0){
            System.out.println("获取锁成功");
            return;
        }
        else {
            // 监听前一个临时节点的状态
            String preIndexPath = childrenList.get(index - 1);
            Stat stat = zooKeeper.exists(LOCK_ROOT_PARH + "/" + preIndexPath,watcher);
            if (stat==null){
                attempLock();
            }else {
                synchronized (watcher){
                    watcher.wait();
                }
            }
        }
    }
    // 释放锁节点
    public void releaseLock()throws Exception {
        //删除临时有序节点
        zooKeeper.delete(this.lockPath,-1);
        zooKeeper.close();
        System.out.println("释放锁成功");
    }
}
